/**
 * 格式化金额
 * @param {number|string} amount - 金额值，支持数字或字符串类型
 * @param {number} [decimalPlaces=2] - 保留的小数点位数，默认为 2
 * @param {string} [roundingMode='round'] - 取整方式，可选值：'floor', 'ceil', 'round'，默认为 'round'
 * @param {boolean} [forceDecimal=false] - 是否强制保留小数位数，默认为 false
 * @returns {string} 格式化后的金额字符串
 */
export function formatAmount(amount, decimalPlaces = 2, roundingMode = 'round', forceDecimal = false) {
  // 验证参数
  if (typeof amount !== 'number' && typeof amount !== 'string') {
    throw new TypeError('amount 必须是数字或字符串类型')
  }

  if (typeof decimalPlaces !== 'number' || decimalPlaces < 0 || !Number.isInteger(decimalPlaces)) {
    throw new TypeError('decimalPlaces 必须是非负整数')
  }

  if (!['floor', 'ceil', 'round'].includes(roundingMode)) {
    throw new TypeError('roundingMode 必须是 "floor", "ceil" 或 "round"')
  }

  if (typeof forceDecimal !== 'boolean') {
    throw new TypeError('forceDecimal 必须是布尔类型')
  }

  // 将金额转换为数字
  const numAmount = Number(amount)
  if (isNaN(numAmount)) {
    throw new Error('amount 必须是一个有效的数字')
  }

  // 处理取整
  let roundedAmount
  switch (roundingMode) {
    case 'floor':
      roundedAmount = Math.floor(numAmount * Math.pow(10, decimalPlaces)) / Math.pow(10, decimalPlaces)
      break
    case 'ceil':
      roundedAmount = Math.ceil(numAmount * Math.pow(10, decimalPlaces)) / Math.pow(10, decimalPlaces)
      break
    case 'round':
    default:
      roundedAmount = Math.round(numAmount * Math.pow(10, decimalPlaces)) / Math.pow(10, decimalPlaces)
      break
  }

  // 转换为字符串并格式化
  const amountStr = roundedAmount.toString()

  // 如果不需要强制保留小数位或者没有小数部分，直接返回
  if (!forceDecimal || decimalPlaces === 0) {
    return numAmount.toFixed(decimalPlaces).replace(/\.?0+$/, '')
  }

  // 需要保留小数位的情况
  if (!amountStr.includes('.')) {
    return `${amountStr}.${'0'.repeat(decimalPlaces)}`
  }

  return amountStr
}

/**
 * 将任意类型的输入值转换为数值类型
 *
 * @param {*} value - 需要转换的值，可以是任意类型
 * @returns {number} 转换后的数值，如果转换失败返回0
 *
 * @description
 * 该函数尝试将传入的任意类型值转换为有效的数值类型。处理逻辑如下：
 * 1. 如果输入为 null、undefined 或布尔值，直接返回0；
 * 2. 如果输入已经是数字类型，则验证是否为 NaN，若是则返回0；
 * 3. 如果输入是字符串类型，则去除两端空白字符后尝试转换为数字，空字符串或无效数字返回0；
 * 4. 对于其他类型（如对象、数组等），尝试使用 Number() 构造函数进行转换，并捕获可能的异常；
 *    如果转换结果为 NaN，则返回0。
 */
export function parseNumber(value) {
  // 先处理特殊值和非字符串/数字类型
  if (value === null || value === undefined || typeof value === 'boolean') {
    return 0
  }

  // 如果已经是数值类型直接返回
  if (typeof value === 'number') {
    return isNaN(value) ? 0 : value
  }

  // 处理字符串类型
  if (typeof value === 'string') {
    // 去除两端空白字符
    const trimmed = value.trim()

    // 空字符串返回0
    if (trimmed === '') {
      return 0
    }

    // 使用Number转换并验证是否为有效数字
    const num = Number(trimmed)
    return isNaN(num) ? 0 : num
  }

  // 处理其他类型（如BigInt、Symbol等）
  try {
    // 尝试转换为数字
    const num = Number(value)
    return isNaN(num) ? 0 : num
  } catch (e) {
    return 0
  }
}
